package com.link.base.base.chiper.service;

import javax.annotation.Resource;

import com.link.core.util.ChiperUtil;
import com.link.core.util.RedisUtil;
import com.link.core.util.redisclient.LinkRedisClient;
import com.link.base.base.chiper.dao.mybatis.mapper.ChiperReadMapper;
import org.springframework.stereotype.Service;
import com.link.base.base.chiper.model.ChiperRead;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;


import java.lang.reflect.Field;
import java.util.List;

/**
 * 针对查询类的字段隐藏加密操作
 *
 * @author: 郑洪达
 * @date: 2019/12/12
 */
@Service
public class ChiperReadServiceImpl extends BasicServiceImpl<ChiperRead> implements ChiperReadService {

    @Resource
    private ChiperReadMapper chiperReadMapper;
    
    @Override
    public BasicMapper<ChiperRead> getBasicMapper() {
        return chiperReadMapper;
    }

    @Override
    public void clearCache(ChiperRead chiperRead) throws Exception {
        LinkRedisClient jedis = null;
        try {
            List<ChiperRead> chiperReadList = chiperReadMapper.queryByExamplePage(chiperRead);
            jedis = RedisUtil.getJedis();
            //清楚原有缓存
            jedis.del(ChiperUtil.LNK_CHIPER_READ_KEY);
            for (ChiperRead chiperReadTemp : chiperReadList) {
                if (("Y").equals(chiperReadTemp.getValid())) {
                    //类与读写操作加密操作按 com.***.***;field;action形势存入redis
                    String  chiperReadInfo = chiperReadTemp.getClassName() + ";" + chiperReadTemp.getFieldName()
                            + ";" + chiperReadTemp.getAction();
                    if ("N".equals(chiperReadTemp.getHideFlag()) && !("None").equals(chiperReadTemp.getAction())) {
                        jedis.lpush(ChiperUtil.LNK_CHIPER_READ_KEY, chiperReadInfo);
                    } else if ("Y".equals(chiperReadTemp.getHideFlag())) {
                        //字符串部分隐藏,添加开始和结束位
                        chiperReadInfo = chiperReadInfo + ";" + chiperReadTemp.getStartIndex() + ";"
                                + chiperReadTemp.getEndIndex();
                        jedis.lpush(ChiperUtil.LNK_CHIPER_READ_KEY, chiperReadInfo);
                    }
                }
            }
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    @Override
    public boolean checkChiper(ChiperRead chiperRead) throws Exception {
        //去除输入字符串空格
        chiperRead.setClassName(chiperRead.getClassName().trim());
        chiperRead.setFieldName(chiperRead.getFieldName().trim());
        //获取类加载器
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz = loader.loadClass(chiperRead.getClassName());
        //需要检测的属性名称
        String fieldname = chiperRead.getFieldName();
        return isFieldExist(clazz,fieldname);
    }

    @Override
    public boolean checkHidePart(ChiperRead chiperRead) throws Exception {
        int start = Integer.valueOf(chiperRead.getStartIndex().trim());
        int end = Integer.valueOf(chiperRead.getEndIndex().trim());
        if (start <= end && start >= 1) {
            chiperRead.setStartIndex(String.valueOf(start));
            chiperRead.setEndIndex(String.valueOf(end));
            return true;
        }
        return false;
    }

    private static boolean isFieldExist(Class clazz, String targetFieldName) throws Exception {
        boolean exist = false;
        // 获取所有的属性数组
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 属性名称
            String currentFieldName = field.getName();
            if (currentFieldName.equals(targetFieldName)) {
                exist = true;
                break;
            }
        }
        // 获取继承类里面的属性值
        Class superClass = clazz.getSuperclass();
        if (null != superClass) {
            Field[] superFields = superClass.getDeclaredFields();
            for (Field superField : superFields) {
                // 属性名称
                String currentFieldName = superField.getName();
                if (currentFieldName.equals(targetFieldName)) {
                    exist = true;
                    break;
                }
            }
        }
        return exist;
    }
}

